package cn.bonoon.services.plugins;

import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.persistence.Query;

import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import cn.bonoon.core.plugins.HolidayService;
import cn.bonoon.entities.plugins.HolidayEntity;
import cn.bonoon.kernel.support.services.AbstractService;

@Service
@Transactional(readOnly = true)
public class HolidayServiceImpl extends AbstractService<HolidayEntity> implements HolidayService {

	@Override
	public HolidayEntity getYear(int year) {
		return __first(HolidayEntity.class, "from HolidayEntity x where x.year=?", year);
	}

	@Override
	public String getMonth(int year, int month) {
		//String[] months = { "january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december" };
		return __first(String.class, "select x." + months[month] + " from HolidayEntity x where x.year=?", year);
	}
	
	private final String[] months = { "january", "february", "march", "april", "may", "june", "july", "august", "september", "october", "november", "december" };

	@Override
	public Object get2Month(int year, int month_1, int month_2) {
		Query query = entityManager.createQuery("select x." + months[month_1] + ", x." + months[month_2] + " from HolidayEntity x where x.year=?");
		List<?> items = query.setParameter(1, year).getResultList();
		return items.isEmpty() ? null : items.get(0);
	}

	final SimpleDateFormat sdf = new SimpleDateFormat("yyyy年MM月dd日");
	@Override
	public Date getBefore(Date date, int workDays) {
		Calendar cal = Calendar.getInstance();
		cal.setTime(date);
		int year = cal.get(Calendar.YEAR);
		int numberOfDay = 0;
		Map<String, String> holyDays = getMap(year-1, year);
		while (numberOfDay < workDays) {
			cal.add(Calendar.DATE, -1);
			String key = sdf.format(cal.getTime());
			if (!holyDays.containsKey(key))// 如果碰到假日，顺延
				numberOfDay++;
		}		

		return cal.getTime();
	}

	private Map<String, String> getMap(int fromYear, int toYear) {
		if (fromYear > toYear) {
			int temp = toYear;
			toYear = fromYear;
			fromYear = temp;
		}

		Map<String, String> map = new HashMap<String, String>();
		for (int year = fromYear; year <= toYear; year++) {
			String ql = "from HolidayEntity x where x.year=? ";
			HolidayEntity v = __first(HolidayEntity.class,ql, year);
			if(v == null){
				continue;
			}
			getHolyDays(year, 1, v.getJanuary(), map);
			getHolyDays(year, 2, v.getFebruary(), map);
			getHolyDays(year, 3, v.getMarch(), map);
			getHolyDays(year, 4, v.getApril(), map);
			getHolyDays(year, 5, v.getMay(), map);
			getHolyDays(year, 6, v.getJune(), map);
			getHolyDays(year, 7, v.getJuly(), map);
			getHolyDays(year, 8, v.getAugust(), map);
			getHolyDays(year, 9, v.getSeptember(), map);
			getHolyDays(year, 10, v.getOctober(), map);
			getHolyDays(year, 11, v.getNovember(), map);
			getHolyDays(year, 12, v.getDecember(), map);
		}
		
		return map;
	}

	private void getHolyDays(int year, int month, String dayStr,
			Map<String, String> map) {
	//	List<Date> r = new ArrayList<Date>();
		String[] days = dayStr.split(",");
		Calendar cal = Calendar.getInstance();
		for (String d : days) {
			cal.set(year,month-1,Integer.parseInt(d));			
			map.put(sdf.format(cal.getTime()),"");
		}
	}
	
}
